import { renderImage } from "maishu-ui-toolkit";
import { ImageService } from "maishu-services-sdk";
import { ShoppingCartService } from "mobile/services/shoppingCartService";
import { component } from "components/common/component";
import { ShoppingService } from "mobile/services/shoppingService";
import React = require("react");
import { SpinerComponent, Status } from "components/common/spiner-component";
import { subscribe } from "common";

export interface Props {
    /** 商品来源 */
    productSourceType: 'category' | 'custom' | 'all',
    /** 图片大小 */
    imageSize: "small" | "medium" | "large",
    /** 商品名称行数 */
    productNameLines: 'singleLine' | 'doubleColumn',
    /** 选取要展示的商品编号 */
    productIds?: string[],
    /** 商品数量 */
    productsCount: number,
    /** 商品类别 */
    categoryId?: string,
    /** 显示商品类别 */
    showCategories: boolean,
}

interface State {
    products: Product[],
    categories: Category[],
    shoppingCartItems: ShoppingCartItem[],
    status?: Status
}


@component({ displayName: "单列商品", icon: "icon-list", introduce: "单列展示商品" })
export class SingleColunmProducts extends SpinerComponent<Props, State> {
    imageService: ImageService;
    shoppingCartService: ShoppingCartService;
    shopService: ShoppingService;

    static defaultProps: Props = {
        imageSize: "small", productNameLines: "singleLine", productSourceType: "all",
        productsCount: 1, showCategories: true,
    }

    constructor(props) {
        super(props);

        this.state = { products: [], shoppingCartItems: [], categories: [] };
        this.imageService = this.createService(ImageService);
        this.shoppingCartService = this.createService(ShoppingCartService);
        this.shopService = this.createService(ShoppingService);
    }

    imageUrl(imageId: string) {
        if (!imageId)
            return;

        if (imageId.startsWith("http://"))
            return imageId;

        return this.imageService.imageSource(imageId, 120, 120)
    }

    async UNSAFE_componentWillReceiveProps(props: Props) {
        if (props.productsCount != this.props.productsCount) {
            let products = await this.shopService.products(props.productsCount);
            this.setState({ products });
        }
    }

    async componentDidMount() {
        // let products = await this.shopService.products(0);
        subscribe(this, ShoppingCartService.items, (items) => {
            this.setState({ shoppingCartItems: items });
        })
        // this.setState({ products });
    }

    async loadData(): Promise<Partial<State> | string> {
        let { categoryId, productsCount, productIds } = this.props;
        let sourceType = this.props.productSourceType;
        let products: Product[]
        if (sourceType == 'category') {
            products = await this.shopService.productsByCategory(productsCount, categoryId)
        }
        else if (sourceType == 'custom') {
            products = productIds ? await this.shopService.productsByIds(productIds) : []
        }
        else {
            products = await this.shopService.products(productsCount);
        }

        let [categories] = await Promise.all([
            this.shopService.categories(),
        ]);

        if (products == null || products.length == 0)
            return "暂无所要显示的商品";

        return { products, categories }
    }

    render() {
        let { imageSize, productNameLines, showCategories } = this.props;
        let { categories, products, shoppingCartItems } = this.state;

        let leftClassName: string, rightClassName: string;
        switch (imageSize) {
            case 'small':
            default:
                leftClassName = 'col-xs-3';
                rightClassName = 'col-xs-9';
                break;
            case 'medium':
                leftClassName = 'col-xs-4';
                rightClassName = 'col-xs-8';
                break;
            case 'large':
                leftClassName = 'col-xs-5';
                rightClassName = 'col-xs-7';
                break;
        }

        let titleClassName = productNameLines == 'singleLine' ? 'name single-line' : 'name double-line';

        return <div className="single-colunm-products">
            {showCategories ? <ul className="categories list-group pull-left">
                {categories.map(o =>
                    <li key={o.Id} className="list-group-item">{o.Name}</li>
                )}
            </ul> : null}
            <div className={showCategories ? "product-list pull-right" : ""}>
                {products.map((p, i) => {
                    let item = shoppingCartItems.filter(o => o.ProductId == p.Id)[0];
                    let itemCount = item ? item.Count : 0;
                    return <React.Fragment key={p.Id}>
                        <div key={p.Id} className={"product single clearfix"}>
                            <div className={leftClassName} style={{ padding: 0 }}
                                onClick={() => this.app.forward("home/product", { id: p.Id })}>
                                <img key={p.Id} className="product-image" src={this.imageUrl(p.ImagePath)} data-url={p.ImagePath}
                                    ref={e => e ? renderImage(e, { imageSize: { width: 120, height: 120 } }) : null} />
                            </div>
                            <div className={rightClassName}>
                                <div className={`${titleClassName} btn-link`} product-id={p.Id}>{p.Name}</div>
                                <div className="price-bar">
                                    <span className="pull-left price-color">￥{p.Price}</span>
                                    <div className="pull-right">
                                        <ProductNumberButton shoppingCartService={this.shoppingCartService} product={p}
                                            count={itemCount} />
                                    </div>
                                </div>
                            </div>
                        </div>
                        {i < products.length - 1 ? <hr style={{}} /> : null}
                    </React.Fragment>
                })}
            </div>
        </div>
    }
}

class ProductNumberButton extends React.Component<{ shoppingCartService: ShoppingCartService, product: Product, count: number }, { count: number }> {
    constructor(props) {
        super(props);
        this.state = { count: this.props.count };
        this.props.shoppingCartService.onChanged(this, (items) => {
            let shoppingCartItem = items.filter(o => o.ProductId == this.props.product.Id)[0];
            if (shoppingCartItem) {
                this.setState({ count: shoppingCartItem.Count });
            }
            else {
                this.setState({ count: 0 })
            }
        })
    }

    decreaseProductCount() {
        let { count } = this.state;
        if (count <= 0)
            return;

        count = count - 1;
        this.setState({ count });
        return this.props.shoppingCartService.setItemCount(this.props.product, count);
    }

    increaseProductCount() {
        let { count } = this.state;
        count = count + 1;
        this.setState({ count });
        return this.props.shoppingCartService.setItemCount(this.props.product, count);
    }

    static getDerivedStateFromProps(props: ProductNumberButton["props"]): Partial<ProductNumberButton["state"]> {
        return { count: props.count };
    }

    render() {
        let { count } = this.state;
        return <div className="buy-button icon-style input-group pull-right">
            <span className="input-group-addon" onClick={() => this.decreaseProductCount()}>
                <i className="icon-minus" />
            </span>
            <input type="number" min={1} className="form-control" value={count}
                style={{ padding: 0, textAlign: "center" }}
                onChange={e => {
                    let count = Number.parseInt(e.target.value);
                    if (!isNaN(count) && count > 0) {
                        this.setState({ count });
                    }
                }} />
            <span className="input-group-addon" onClick={() => this.increaseProductCount()}>
                <i className="icon-plus" />
            </span>
        </div>
    }
}

